
import 'dart:typed_data';

import 'package:audio_session/audio_session.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter_sound_platform_interface/flutter_sound_platform_interface.dart';
class SoundUtil {
  /// 单例实例：全局唯一的音频播放管理器
  /// 通过私有构造函数 + 静态常量实例，强制外部只能通过 `SoundUtil.instance` 访问，确保单例特性
  static final SoundUtil instance = SoundUtil._();

  /// 私有构造函数：禁止外部通过 `new SoundUtil()` 创建实例，保障单例唯一性
  SoundUtil._();

  /// FlutterSound 播放器核心实例
  /// 封装了底层音频播放能力（如 Android 的 MediaPlayer、iOS 的 AVAudioPlayer）
  final FlutterSoundPlayer _player = FlutterSoundPlayer();

  /// 初始化播放器：打开底层音频设备，建立播放资源
  /// 【注意】需在调用播放相关方法（如 startStreamPlayer）前执行，建议在应用初始化或首次使用时调用
  /// @return 无返回值，通过 Future 标识初始化完成状态
  Future<void> initPlayer() async {
    await _player.openPlayer();
    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration(
      avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
      avAudioSessionCategoryOptions:
      AVAudioSessionCategoryOptions.allowBluetooth |
      AVAudioSessionCategoryOptions.defaultToSpeaker,
      avAudioSessionMode: AVAudioSessionMode.spokenAudio,
      avAudioSessionRouteSharingPolicy:
      AVAudioSessionRouteSharingPolicy.defaultPolicy,
      avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none
    ));
  }

  /// 启动流式播放模式：初始化播放器为“流式接收-实时播放”状态
  /// 适用于音频数据分段接收的场景（如服务端逐段推送 TTS 音频），避免等待完整音频文件下载导致的延迟
  /// @return 无返回值，通过 Future 标识播放模式初始化完成
  Future<void> startStreamPlayer() async {
    await _player.startPlayerFromStream(
        codec: Codec.pcm16,        // 播放编码格式：16位 PCM 原始数据（与服务端返回的解码格式一致）
        numChannels: 1,           // 声道数：单声道（语音场景常用，减少数据量）
        sampleRate: 16000,        // 采样率：16kHz（语音识别/合成的标准采样率，确保音质匹配）
        // interleaved: false,    // 声道数据是否交错（单声道场景无需配置，默认 false 即可）
        // bufferSize: 100,       // 播放缓冲区大小（单位：毫秒，默认值可满足多数场景，低延迟需求可减小）
        whenFinished: () {        // 播放完全部数据后的回调（可用于重置状态、触发下一轮播放等）
          // 此处可扩展播放结束后的业务逻辑，例如：
          // print("音频播放完成");
          // 重置播放器状态、释放临时资源等
        }
    );
    await _player.setVolume(1);
    // 预留播放速度控制接口（如需支持倍速播放，可通过此方法配置，例如 _player.setSpeed(1.2)）
    // _player.setSpeed(speed);
  }

  /// 向播放器写入音频数据块：流式播放的核心方法
  /// 接收解码后的 PCM 原始数据，封装为 FlutterSound 支持的格式后，喂给播放器实时播放
  /// @param audioBytes：16位 PCM 格式的音频字节数据（需与 startStreamPlayer 配置的参数匹配：单声道、16kHz 采样率）
  /// 【注意】数据格式必须与初始化时的 codec、numChannels、sampleRate 严格一致，否则会出现播放杂音或无法播放
  void feedAudioChunk(Uint8List audioBytes) {
    // 将原始字节数据封装为 FlutterSound 流式播放专用的数据结构（FoodData）
    // FoodData 是 FlutterSound 定义的“音频数据单元”，用于流式传输时的逐段数据承载
    FoodData food = FoodData(audioBytes);

    // 注：注释的代码 `_player.feedFromStream(audioBytes)` 是 FlutterSound 旧版本的 API
    // 新版本中推荐使用 foodSink 接口，通过“生产者-消费者”模式传递数据，稳定性更高
    // 判空处理：避免播放器未初始化或已关闭时调用导致空指针异常
    _player.foodSink?.add(food);
  }

  /// 停止流式播放：释放播放资源，终止当前音频输出
  /// 【注意】播放结束后必须调用，避免音频资源泄露（如占用扬声器、耗电等）
  /// @return 无返回值，通过 Future 标识停止操作完成
  Future<void> stopStreamPlayer() async {
    // 1. 先关闭 foodSink：通知播放器“后续无数据输入”，触发播放器处理剩余缓存数据后停止
    // 若不关闭 foodSink 直接停止播放器，可能导致缓存数据未播放完全或资源释放不彻底
    await _player.foodSink?.close();

    // 2. 停止播放器：释放底层音频设备资源（如关闭扬声器占用、释放音频线程）
    await _player.stopPlayer();
  }

  /// （可选扩展）释放播放器资源：应用退出或长期不使用时调用，彻底释放内存
  /// 【注意】调用后若需再次使用，需重新调用 initPlayer() 初始化
  Future<void> releasePlayer() async {
    await _player.closePlayer();
  }

  /// （可选扩展）设置播放音量：动态调整当前播放的音量大小
  /// @param volume：音量值，范围 0.0（静音）~ 1.0（最大音量）
  void setVolume(double volume) {
    if (volume < 0.0 || volume > 1.0) {
      throw ArgumentError("音量值必须在 0.0 ~ 1.0 之间");
    }
    _player.setVolume(volume);
  }
}